package com.hmall.search.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.hmall.api.item.client.ItemClient;
import com.hmall.api.item.dto.ItemDTO;
import com.hmall.search.domain.dto.PageDTO;
import com.hmall.search.domain.po.ItemDoc;
import com.hmall.search.domain.query.ItemPageQuery;
import com.hmall.search.service.ISearchService;
import lombok.RequiredArgsConstructor;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Service;

import java.security.Key;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @create: 张曦文
 * 日期 :2025/11/9 17:21
 * 功能 :
 **/
@Service
@RequiredArgsConstructor
public class ISearchServiceImpl implements ISearchService {
    private final ItemClient itemClient;

    private final RestHighLevelClient client;

    @Override
    public PageDTO<ItemDTO> search(ItemPageQuery query) throws Exception {
        String key = query.getKey();
        SearchRequest request = new SearchRequest("items");
        SearchSourceBuilder searchSourceBuilder = getSearchSourceBuilder(query, key);

        // 排序
        if (StrUtil.isNotBlank(query.getSortBy())) {
            searchSourceBuilder.sort(query.getSortBy(), query.getIsAsc() ? SortOrder.ASC : SortOrder.DESC);
        }

        // 分页
        Integer from = (query.getPageNo() - 1) * query.getPageSize();
        searchSourceBuilder.from(from);
        searchSourceBuilder.size(query.getPageSize());

        // 高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        searchSourceBuilder.highlighter(highlightBuilder);


        request.source(searchSourceBuilder);


        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);

        long total = searchResponse.getHits().getTotalHits().value;

        List<ItemDTO> list = CollUtil.newArrayList();

        SearchHit[] hits = searchResponse.getHits().getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            ItemDoc itemDoc = JSONUtil.toBean(sourceAsString, ItemDoc.class);


            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if (highlightFields != null) {
                HighlightField highlightField = highlightFields.get("name");
                if (highlightField != null) {
                    itemDoc.setName(highlightField.getFragments()[0].string());
                }
            }


            ItemDTO itemDTO = BeanUtil.toBean(itemDoc, ItemDTO.class);
            list.add(itemDTO);

        }

        PageDTO pageDTO = new PageDTO();
        pageDTO.setTotal(total);
        pageDTO.setList(list);

        return pageDTO;



    }

    private SearchSourceBuilder getSearchSourceBuilder(ItemPageQuery query, String key) {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        if (StrUtil.isBlank(key)) {
            //查询全部
            searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        }else {
            //组合查询
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            boolQueryBuilder.must(QueryBuilders.matchQuery("name", key));
             //判断是否分类
            if(StrUtil.isNotBlank(query.getCategory())){
                boolQueryBuilder.filter(QueryBuilders.matchQuery("category", query.getCategory()));
            }
            //判断是否有品牌
            if(StrUtil.isNotBlank(query.getBrand())){
                boolQueryBuilder.filter(QueryBuilders.matchQuery("brand", query.getBrand()));
            }
            //判断是否有价格
            if(query.getMinPrice() != null && query.getMaxPrice() != null){
                boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").from(query.getMinPrice()).to(query.getMaxPrice()));
            }
            searchSourceBuilder.query(boolQueryBuilder);
        }
        return searchSourceBuilder;
    }

    @Override
    public void initEs() throws Exception {
        //使用微服务调用
        Integer pageNo = 1;
        while (true) {
            List<ItemDTO> itemDTOS = itemClient.queryItemByPage(pageNo, 100);
            if (CollUtil.isEmpty(itemDTOS)) {
                return;
            }
            BulkRequest bulkRequest = new BulkRequest();
            for (ItemDTO itemDTO : itemDTOS) {
                ItemDoc itemDoc = BeanUtil.toBean(itemDTO, ItemDoc.class);
                IndexRequest indexRequest = new IndexRequest("items");
                indexRequest.id(itemDoc.getId().toString());
                String jsonStr = JSONUtil.toJsonStr(itemDoc);
                indexRequest.source(jsonStr, XContentType.JSON);
                bulkRequest.add(indexRequest);
            }
            client.bulk(bulkRequest, RequestOptions.DEFAULT);
            pageNo++;
        }
    }

    @Override
    public Map<String, List<String>> filters(ItemPageQuery query) throws Exception{
        String key = query.getKey();

        SearchRequest request = new SearchRequest("items");

        SearchSourceBuilder searchSourceBuilder = getSearchSourceBuilder(query, key);



        searchSourceBuilder.aggregation(AggregationBuilders.terms("brandAgg").field("brand").size(50));
        searchSourceBuilder.aggregation(AggregationBuilders.terms("categoryAgg").field("category").size(50));

        request.source(searchSourceBuilder);

        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);

        Aggregations aggregations = searchResponse.getAggregations();

        // 处理品牌

        Terms brandAggTerms = aggregations.get("brandAgg");
        List<? extends Terms.Bucket> buckets = brandAggTerms.getBuckets();

        List<String> brandList = new ArrayList();

        for (Terms.Bucket bucket : buckets) {
            String brandName = bucket.getKeyAsString();
            brandList.add(brandName);

        }
        // 处理分类

        Terms categoryAggTerms = aggregations.get("categoryAgg");
        List<? extends Terms.Bucket> buckets1 = categoryAggTerms.getBuckets();

        List<String> categoryList = new ArrayList();

        for (Terms.Bucket bucket : buckets1) {
            String categoryName = bucket.getKeyAsString();
            categoryList.add(categoryName);

        }

        Map<String, List<String>> result = Map.of("brand", brandList, "category", categoryList);

        return result;
    }
}
